package cn.gene.timeyan.ums.webapi.ums.service.impl;

import cn.gene.timeyan.common.constant.RedisConstants;
import cn.gene.timeyan.common.exception.TimeyanServiceException;
import cn.gene.timeyan.common.restful.ResponseCode;
import cn.gene.timeyan.common.utils.FormUtils;
import cn.gene.timeyan.pojo.ums.dto.AddHonorDTO;
import cn.gene.timeyan.pojo.ums.dto.AddNewUserHonor;
import cn.gene.timeyan.pojo.ums.vo.HonorVO;
import cn.gene.timeyan.ums.service.IHonorService;
import cn.gene.timeyan.ums.webapi.ums.mapper.HonorMapper;
import cn.gene.timeyan.ums.webapi.ums.mapper.HonorUserMapper;
import cn.gene.timeyan.ums.webapi.ums.utils.PictureUtils;
import com.alibaba.fastjson.JSON;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

@Service
@DubboService
public class HonorServiceImpl implements IHonorService {
    private static String FILEPATH = System.getProperty("user.dir") + System.getProperty("file.separator")+"picture"+ System.getProperty("file.separator") + "honor";
    @Autowired
    private HonorMapper honorMapper;
    @Autowired
    private HonorUserMapper userHonorMapper;
    @Autowired
    @Qualifier("redisTemplate3")
    private RedisTemplate redisTemplate;
    /**
     * 获取用户的徽章列表
     * @param userId
     * @return
     */
    @Override
    public List<HonorVO> getHonorList(Long userId) {
        String honorKey=RedisConstants.HONOR_LIST;
        String userHonorKey=RedisConstants.USER_HONOR_LIST+userId;
        List<HonorVO> list=new LinkedList<>();
        //是否有缓存
        if (redisTemplate.hasKey(honorKey)){
            Set<String> ids=redisTemplate.opsForZSet().reverseRange(honorKey,0,-1);
            if (redisTemplate.hasKey(userHonorKey)){
                Set<String> hasIds=redisTemplate.opsForZSet().reverseRange(userHonorKey,0,-1);
                for (String id:hasIds){
                    System.out.println(hasIds);
                    HonorVO honorVO= JSON.parseObject(redisTemplate.opsForHash().get(honorKey+":detail",id).toString(),HonorVO.class);
                    System.out.println("honor="+honorVO);
                    honorVO.setHas('1');
                    honorVO.setGainTime(LocalDateTime.ofEpochSecond(JSON.parseObject(redisTemplate.opsForHash().get(userHonorKey+":detail",userId+"&"+id).toString(), Long.class),0, ZoneOffset.of("+8")));

                    list.add(honorVO);
                }
                for (String id:ids) {
                    HonorVO honorVO= JSON.parseObject(redisTemplate.opsForHash().get(honorKey+":detail",id).toString(),HonorVO.class);
                    //有该徽章
                    if (list.contains(honorVO)){
                        continue;
                    }
                    list.add(honorVO);
                }
                return list;
            }
            //没有用户获取徽章的缓存
            List<HonorVO> honorVOs=userHonorMapper.getUserHonorListByUserId(userId);
            for (HonorVO honorVO:honorVOs){
                honorVO.setHas('1');
                list.add(honorVO);
                double time= FormUtils.parseTimeByLocalDateTime(honorVO.getGainTime());
                redisTemplate.opsForZSet().add(userHonorKey,""+honorVO.getHonorId(),time);
                redisTemplate.opsForHash().put(userHonorKey+":detail",userId+"&"+honorVO.getHonorId(),JSON.toJSON(honorVO.getGainTime().toEpochSecond(ZoneOffset.of("+8"))));

            }
            for (String id:ids) {
                HonorVO honorVO= JSON.parseObject(redisTemplate.opsForHash().get(honorKey+":detail",id).toString(),HonorVO.class);
                if (honorVOs.contains(honorVO)){continue;}
                list.add(honorVO);
            }
            return list;
        }
        //没缓存
        //获取总徽章列表
        List<HonorVO> honorVOList=honorMapper.getHonorList();
        for (HonorVO honorVO:honorVOList) {
            honorVO.setHas('0');
            double time= FormUtils.parseTimeByLocalDateTime(honorVO.getEndTime());
            redisTemplate.opsForZSet().add(honorKey,""+honorVO.getHonorId(),time);
            redisTemplate.opsForHash().put(honorKey+":detail",""+honorVO.getHonorId(),JSON.toJSON(honorVO));
        }
        //获取该用户拥有的徽章列表
        List<HonorVO> honorVOs=userHonorMapper.getUserHonorListByUserId(userId);
        System.out.println(honorVOs);
        for (HonorVO honorVO:honorVOs){
            honorVO.setHas('1');
            list.add(honorVO);
            double time= FormUtils.parseTimeByLocalDateTime(honorVO.getGainTime());
            redisTemplate.opsForZSet().add(userHonorKey,""+honorVO.getHonorId(),time);
            redisTemplate.opsForHash().put(userHonorKey+":detail",userId+"&"+honorVO.getHonorId(),JSON.toJSON(honorVO.getGainTime().toEpochSecond(ZoneOffset.of("+8"))));
        }
        System.out.println("用户有的:"+list);
        Set<String> ids=redisTemplate.opsForZSet().reverseRange(honorKey,0,-1);
        for (String id:ids) {
            HonorVO honorVO= JSON.parseObject(redisTemplate.opsForHash().get(honorKey+":detail",id).toString(),HonorVO.class);
            if (honorVOs.contains(honorVO)){continue;}
            list.add(honorVO);
        }
        System.out.println("结果:"+list);
        return list;
    }

    /**
     * 添加新徽章信息
     * @param honorDTO
     */
    @Override
    public void addNewHonor(AddHonorDTO honorDTO) {
        System.out.println(honorDTO);
        if (honorDTO==null || honorDTO.toString().isEmpty()){
            throw new TimeyanServiceException(ResponseCode.INTERNAL_SERVER_ERROR,"请输入合法参数");
        }
        //判断是否已有
        int line=honorMapper.selectHonorByHonorName(honorDTO.getHonorName());
        if (line>0){
            //已有该名称的徽章
            throw new TimeyanServiceException(ResponseCode.ERR_UNIQUE,"该徽章信息已存在");
        }
        line=honorMapper.insertNewHonor(honorDTO);
        if (line<1){
            throw new TimeyanServiceException(ResponseCode.ERR_INSERT,"插入失败，请重试");
        }
    }

    /**
     * 添加用户获取徽章信息
     * @param addNewUserHonor
     */
    @Override
    public void addNewUserHonor(AddNewUserHonor addNewUserHonor) {
        String honorKey=RedisConstants.HONOR_LIST;
        String userHonorKey=RedisConstants.USER_HONOR_LIST+addNewUserHonor.getUserId();
        LocalDateTime gainTime=LocalDateTime.now();
        String available=honorMapper.getAvailableByHonorId(addNewUserHonor.getHonorId());
        int line=userHonorMapper.verifyUserHonor(addNewUserHonor.getHonorId(),addNewUserHonor.getUserId());
        if (line>0){
            throw new TimeyanServiceException(ResponseCode.ERR_INSERT,"该用户已经获取过该徽章");
        }
        //不可获取，默认可以获取
        if ("0".equals(available)){
            throw new TimeyanServiceException(ResponseCode.ERR_INSERT,"该徽章已经不可获得");
        }
        if (redisTemplate.hasKey(userHonorKey+":detail")){
            //有缓存
            if (!redisTemplate.opsForHash().hasKey(honorKey+":detail",""+addNewUserHonor.getHonorId())){
                //还未添加到列表
                HonorVO honorVO=honorMapper.getHonorById(addNewUserHonor.getHonorId());
                honorVO.setHas('0');
                double time= FormUtils.parseTimeByLocalDateTime(honorVO.getEndTime());
                redisTemplate.opsForZSet().add(honorKey,""+honorVO.getHonorId(),time);
                redisTemplate.opsForHash().put(honorKey+":detail",""+honorVO.getHonorId(),JSON.toJSON(honorVO));
            }
            HonorVO honor= JSON.parseObject(redisTemplate.opsForHash().get(honorKey+":detail",""+addNewUserHonor.getHonorId()).toString(),HonorVO.class);
            LocalDateTime end=honor.getEndTime();
            //当前时间在结束时间之前
            if (end.isAfter(LocalDateTime.now())){
                double time=FormUtils.parseTimeByLocalDateTime(gainTime);
                redisTemplate.opsForZSet().add(userHonorKey,addNewUserHonor.getUserId()+"&"+addNewUserHonor.getHonorId(),time);
                redisTemplate.opsForHash().put(userHonorKey+":detail",addNewUserHonor.getUserId()+"&"+addNewUserHonor.getHonorId(),JSON.toJSON(gainTime.toEpochSecond(ZoneOffset.of("+8"))));
                userHonorMapper.addUserHonorByRedis(addNewUserHonor.getUserId(), addNewUserHonor.getHonorId(), gainTime);
                return;
            }else{
                throw new TimeyanServiceException(ResponseCode.ERR_INSERT,"该徽章已经不可获得");
            }
        }
        LocalDateTime end=honorMapper.getEndTimeByHonorId(addNewUserHonor.getHonorId());
        if (end.isAfter(LocalDateTime.now())){
            userHonorMapper.addUserHonorByRedis(addNewUserHonor.getUserId(), addNewUserHonor.getHonorId(), gainTime);
        }else{
            throw new TimeyanServiceException(ResponseCode.ERR_INSERT,"该徽章已经不可获得");
        }
    }

    /**
     * 修改指定徽章名称
     * @param name
     * @param honorId
     */
    @Override
    public void updateHonorName(String name, Long honorId) {
        if (name==null || honorId==null){
            throw new TimeyanServiceException(ResponseCode.INTERNAL_SERVER_ERROR,"请输入合法参数");
        }
        int line=honorMapper.updateHonorName(name,honorId);
        if (line<1){
            throw new TimeyanServiceException(ResponseCode.ERR_UPDATE,"更新失败，请重试");
        }
        String url=honorMapper.getHonorUrlByHonorId(honorId);
        System.out.println(url);
        if (url!=null&&!url.isEmpty()){
            try {
                String suf=url.substring(url.lastIndexOf("."));
                String iconUrl=FILEPATH+System.getProperty("file.separator")+name+suf;
                honorMapper.updateUrlByHonorId(honorId,"honor\\"+name+suf);
                File file=new File(url);
                file.renameTo(new File(iconUrl));
            }catch (Exception e){
                throw new TimeyanServiceException(ResponseCode.ERR_UPDATE,"更新失败，请重试");
            }
        }
    }

    /**
     * 修改徽章图像
     * @param imgFile
     * @param honorId
     */
    @Override
    public void updateHonorImg(MultipartFile imgFile, Long honorId) {
        if (imgFile.isEmpty() || honorId==null){
            throw new TimeyanServiceException(ResponseCode.INTERNAL_SERVER_ERROR,"请输入合法参数");
        }
        //文件后缀
        String suffix=imgFile.getOriginalFilename().substring(imgFile.getOriginalFilename().lastIndexOf("."));
        //文件名
        String name=honorMapper.selectHonorByHonorId(honorId)+suffix;
        if (!PictureUtils.validate(name)){
            throw new TimeyanServiceException(ResponseCode.ERR_UPDATE,"更新失败，文件格式不支持");
        }
        //文件保存目录
        File file = new File(FILEPATH);
        if (!file.exists()) {
            file.mkdirs();
        }
        System.out.println(file.exists());
        String fileName=FILEPATH + System.getProperty("file.separator") + name;
        File item = new File(fileName);
        System.out.println();
        try {
            imgFile.transferTo(item);
            System.out.println(item.exists());
        } catch (IOException e) {
            System.out.println(item.exists());
            throw new TimeyanServiceException(ResponseCode.ERR_UPDATE,"更新失败，请重试");
        }
        int line=honorMapper.updateHonorImg("/honor/"+name+suffix,honorId);
        if (line<1){
            throw new TimeyanServiceException(ResponseCode.ERR_UPDATE,"更新失败，请重试");
        }
    }

    /**
     *修改结束时间
     * @param end
     * @param honorId
     */
    @Override
    public void updateHonorEndTime(LocalDateTime end, Long honorId) {
        if (end==null || honorId==null){
            throw new TimeyanServiceException(ResponseCode.INTERNAL_SERVER_ERROR,"请输入合法参数");
        }
        int line=honorMapper.updateHonorEnd(end,honorId);
        if (line<1){
            throw new TimeyanServiceException(ResponseCode.ERR_UPDATE,"更新失败，请重试");
        }
    }

    /**
     *修改是否可获得
     * @param available
     * @param honorId
     */
    @Override
    public void updateHonorAvailable(Character available, Long honorId) {
        if (available==null || honorId==null){
            throw new TimeyanServiceException(ResponseCode.INTERNAL_SERVER_ERROR,"请输入合法参数");
        }
        int line=honorMapper.updateHonorAvailable(available,honorId);
        if (line<1){
            throw new TimeyanServiceException(ResponseCode.ERR_UPDATE,"更新失败，请重试");
        }
    }

    /**
     * 修改获取方式
     * @param way
     * @param honorId
     */
    @Override
    public void updateHonorAcquireWay(String way, Long honorId) {
        if (way==null || honorId==null){
            throw new TimeyanServiceException(ResponseCode.INTERNAL_SERVER_ERROR,"请输入合法参数");
        }
        int line=honorMapper.updateHonorAcquireWay(way,honorId);
        if (line<1){
            throw new TimeyanServiceException(ResponseCode.ERR_UPDATE,"更新失败，请重试");
        }
    }
}
